package com.tanhua.app.controllerservice;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.tanhua.api.db.UserInfoApi;
import com.tanhua.api.mongo.CommentApi;
import com.tanhua.api.mongo.PublishApi;
import com.tanhua.domain.db.UserInfo;
import com.tanhua.domain.mongo.Comment;
import com.tanhua.domain.mongo.Publish;
import com.tanhua.domain.vo.CommentVo;
import com.tanhua.domain.vo.PageBeanVo;
import com.tanhua.domain.vo.PublishVo;
import com.tanhua.domain.vo.UserHolder;
import com.tanhua.template.OssTemplate;
import com.tanhua.utils.RelativeDateFormat;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class QuanZiService {

    @Autowired
    private OssTemplate ossTemplate;

    @Reference
    private PublishApi publishApi;
    @Reference
    private UserInfoApi userInfoApi;
    @Reference
    private CommentApi commentApi;

    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    public ResponseEntity movements(Publish publish, MultipartFile[] imageContent) throws IOException {
        Long userId = UserHolder.getUser().getId();
        Boolean key = stringRedisTemplate.hasKey("Freeze" + userId);
        String freezingRange = stringRedisTemplate.opsForValue().get("Freeze" + userId);
        if (key&&freezingRange.equals("3")){
            throw new RuntimeException("您的发布动态功能已被冻结");
        }

        //1 将图片上传到了oss上
        if(imageContent.length>0){
            List<String> medias=new ArrayList<String>();
            for (MultipartFile multipartFile : imageContent) {
                String path = ossTemplate.upload(multipartFile.getOriginalFilename(), multipartFile.getInputStream());
                medias.add(path);
            }
            publish.setMedias(medias);
        }

        //2 将文字动态保存到publish动态表
        publish.setState(0); //0：代表未审核  1：审核通过  2：审核失败
        publish.setUserId(userId);
        publish.setCreated(System.currentTimeMillis());
        // 图片 文字 和state=0保存到数据库
        String publishId = publishApi.save(publish);

        //审核(mq)
                //通过了--去做修改  state=1
                //不通过---去做修改 state=2
        rocketMQTemplate.convertAndSend("tanhua-quanzi",publishId);


        return ResponseEntity.ok(null);
    }

    public ResponseEntity findMyInfo(Integer page, Integer pagesize, long userId) {

        // 根据当前用户id查询个人动态表 然后在根据个人动态表的publish去动态发布表查询个人的所有动态（分页）
        PageBeanVo pageBeanVo=publishApi.findMyPublish(page,pagesize,userId);
        // 根据用户的id查询当前这个用户的信息 userInfo
        UserInfo userInfo = userInfoApi.findUserInfo(userId);

        // 将个人动态publish和个人信息userInfo封装给一个vo
        List<Publish> items = (List<Publish>) pageBeanVo.getItems();
        List<PublishVo> publishVoList=new ArrayList<PublishVo>();
        if(CollectionUtil.isNotEmpty(items)){
            for (Publish publish : items) {
                PublishVo vo = new PublishVo();
                BeanUtil.copyProperties(userInfo,vo);
                vo.setUserId(userInfo.getId());
                vo.setTags(userInfo.getTags().split(","));

                BeanUtil.copyProperties(publish,vo);
                vo.setId(publish.getId().toString());
                vo.setImageContent(publish.getMedias().toArray(new String[]{}));
                vo.setCreateDate(RelativeDateFormat.format(new Date(publish.getCreated())));
                vo.setDistance("520公里");
                //点赞的图标是否高亮  0：不高亮  1：高亮
                vo.setHasLiked(0);

                //只要状态为审核通过
                if(publish.getState()==1){
                    publishVoList.add(vo);
                }
            }
        }
        // 将这个vo给pageBean进行返回
        pageBeanVo.setItems(publishVoList);

        return ResponseEntity.ok(pageBeanVo);
    }


    public ResponseEntity findFriendsInfo(Integer page, Integer pagesize) {

        // 根据当前用户id查询时间线表 然后在根据个人动态表的publish去动态发布表查询个人的所有动态（分页）
        PageBeanVo pageBeanVo=publishApi.findFriendsInfo(page,pagesize,UserHolder.getUser().getId());

        List<Publish> items = (List<Publish>) pageBeanVo.getItems();

        List<PublishVo> publishVoList=new ArrayList<PublishVo>();
        if(CollectionUtil.isNotEmpty(items)){
            for (Publish publish : items) {
                // 根据好友id查询当前这个用户的信息 userInfo
                UserInfo userInfo = userInfoApi.findUserInfo(publish.getUserId());
                // 将个人动态publish和个人信息userInfo封装给一个vo
                PublishVo vo = new PublishVo();
                vo.setUserInfo(userInfo); //用户信息
                vo.setPublish(publish);  //动态信息
                vo.setId(publish.getId().toString());

                Boolean flg = stringRedisTemplate.hasKey(StrUtil.format("publish_like_comment_{}_{}",UserHolder.getUser().getId(),publish.getId()));
                if(flg){
                    vo.setHasLiked(1); //高亮
                }else{
                    vo.setHasLiked(0); //不高亮
                }

                if(publish.getState()==1) {
                    publishVoList.add(vo);
                }
            }
        }

        // 将这个vo给pageBean进行返回
        pageBeanVo.setItems(publishVoList);

        return ResponseEntity.ok(pageBeanVo);
    }



    private PageBeanVo formRedis(Integer page, Integer pagesize, Long userId) {

        //1 从redis中获取数据
        String pids = stringRedisTemplate.opsForValue().get("QUANZI_PUBLISH_RECOMMEND_" + userId);
        //没有推荐的 就让PageBeanVo=null
        if(pids==null){
            return null;
        }
        //有推荐的
        String[] pidarr = pids.split(",");
        Integer count=pidarr.length;

        //实现分页
        int start=(page-1)*pagesize;
        if(start>count){
            return null;
        }
        int end=page*pagesize;
        if(end>count){
            end=count;
        }

        List<Publish> publishList=new ArrayList();
        for(int i=start;i<end;i++){
            Publish publish=publishApi.findPid(Long.parseLong(pidarr[i]));
            publishList.add(publish);
        }

        return new PageBeanVo(page,pagesize,count.longValue(),publishList);
    }

    public ResponseEntity findRecommendInfo(Integer page, Integer pagesize) {

        //去查询大数据给当前用户推荐的动态（redis）
        PageBeanVo pageBeanVo=formRedis(page,pagesize,UserHolder.getUser().getId());

        if(pageBeanVo==null){
            //recommend_quanzi假数据
            // 根据当前用户id查询推荐表 然后在根据个人动态表的publish去动态发布表查询个人的所有动态（分页）
            pageBeanVo=publishApi.findRecommendInfo(page,pagesize,UserHolder.getUser().getId());
        }

        // 根据用户的id查询当前这个用户的信息
        List<Publish> items = (List<Publish>) pageBeanVo.getItems();

        List<PublishVo> publishVoList=new ArrayList<PublishVo>();
        if(CollectionUtil.isNotEmpty(items)){
            for (Publish publish : items) {
                // 根据好友id查询当前这个用户的信息 userInfo
                UserInfo userInfo = userInfoApi.findUserInfo(publish.getUserId());
                // 将个人动态publish和个人信息userInfo封装给一个vo
                PublishVo vo = new PublishVo();
                vo.setUserInfo(userInfo); //用户信息
                vo.setPublish(publish);  //动态信息
                vo.setId(publish.getId().toString());


                Boolean flg = stringRedisTemplate.hasKey(StrUtil.format("publish_like_comment_{}_{}",UserHolder.getUser().getId(),publish.getId()));
                if(flg){
                    vo.setHasLiked(1); //高亮
                }else{
                    vo.setHasLiked(0); //不高亮
                }

                Boolean flg2 = stringRedisTemplate.hasKey(StrUtil.format("publish_love_comment_{}_{}",UserHolder.getUser().getId(),publish.getId()));
                if(flg){
                    vo.setHasLoved(1); //喜欢不高亮
                }else{
                    vo.setHasLoved(0); //喜欢不高亮
                }

                if(publish.getState()==1) {
                    publishVoList.add(vo);
                }
            }
        }
        // 将个人动态publish和个人信息userInfo封装给一个vo
        // 将这个vo给pageBean进行返回
        pageBeanVo.setItems(publishVoList);
        return ResponseEntity.ok(pageBeanVo);
    }



    //点赞
    public ResponseEntity like(String publishId) {

        //封装数据到实体comment中（可变）
        Comment comment = new Comment();
        comment.setPublishId(new ObjectId(publishId));
        comment.setCommentType(1); //1点赞 2评论 3 喜欢
        comment.setPubType(1); //1 圈子 2 小视频  3 回帖
        comment.setUserId(UserHolder.getUser().getId());
        //操作mongodb
        Long count = commentApi.tongyong(comment);
        //记录标识到redis中（1：代表当前用户对指定的动态id做过点赞）
        stringRedisTemplate.opsForValue().set(  StrUtil.format("publish_like_comment_{}_{}",UserHolder.getUser().getId(),publishId),    "1");
        //返回数量
        return ResponseEntity.ok(count.intValue());
    }

    //喜欢
    public ResponseEntity love(String publishId) {
        //封装数据到实体comment中（可变）
        Comment comment = new Comment();
        comment.setPublishId(new ObjectId(publishId));
        comment.setCommentType(3); //1点赞 2评论 3 喜欢
        comment.setPubType(1); //1 圈子 2 小视频  3 回帖
        comment.setUserId(UserHolder.getUser().getId());
        //操作mongodb
        Long count = commentApi.tongyong(comment);
        //记录标识到redis中（1：代表当前用户对指定的动态id做过点赞）
        stringRedisTemplate.opsForValue().set(  StrUtil.format("publish_love_comment_{}_{}",UserHolder.getUser().getId(),publishId),    "1");
        //返回数量
        return ResponseEntity.ok(count.intValue());
    }

    //评论
    public ResponseEntity pinglun(String publishId,String content) {
        Long userId = UserHolder.getUser().getId();
        Boolean key = stringRedisTemplate.hasKey("Freeze" + userId);
        String freezingRange = stringRedisTemplate.opsForValue().get("Freeze" + userId);

        if (key&&freezingRange.equals("2")){
            throw new RuntimeException("您的评论功能已被冻结");
        }
        //封装数据到实体comment中（可变）
        Comment comment = new Comment();
        comment.setPublishId(new ObjectId(publishId));

        comment.setCommentType(2); //1点赞 2评论 3 喜欢
        comment.setContent(content); //评论内容

        comment.setPubType(1); //1 圈子 2 小视频  3 回帖
        comment.setUserId(userId);
        //操作mongodb
        Long count = commentApi.tongyong(comment);
        //返回数量
        return ResponseEntity.ok(count.intValue());
    }

    //取消点赞
    public ResponseEntity unLike(String publishId) {
        //封装数据到实体comment中（可变）
        Comment comment = new Comment();
        comment.setPublishId(new ObjectId(publishId));
        comment.setCommentType(1); //1点赞 2评论 3 喜欢
        comment.setPubType(1); //1 圈子 2 小视频  3 回帖
        comment.setUserId(UserHolder.getUser().getId());
        //操作mongodb
        Long count = commentApi.tongyong2(comment);
        //记录标识到redis中（1：代表当前用户对指定的动态id做过点赞）
        stringRedisTemplate.delete(  StrUtil.format("publish_like_comment_{}_{}",UserHolder.getUser().getId(),publishId));
        //返回数量
        return ResponseEntity.ok(count.intValue());
    }

    //取消喜欢
    public ResponseEntity unLove(String publishId) {
        //封装数据到实体comment中（可变）
        Comment comment = new Comment();
        comment.setPublishId(new ObjectId(publishId));
        comment.setCommentType(3); //1点赞 2评论 3 喜欢
        comment.setPubType(1); //1 圈子 2 小视频  3 回帖
        comment.setUserId(UserHolder.getUser().getId());
        //操作mongodb
        Long count = commentApi.tongyong2(comment);
        //记录标识到redis中（1：代表当前用户对指定的动态id做过点赞）
        stringRedisTemplate.delete(StrUtil.format("publish_love_comment_{}_{}",UserHolder.getUser().getId(),publishId));
        //返回数量
        return ResponseEntity.ok(count.intValue());
    }

    public ResponseEntity info(String publishId) {

        // 带着id查询动态
        Publish publish=publishApi.findById(publishId);
        // 根据动态中发布人的id查询用户详情
        UserInfo userInfo = userInfoApi.findUserInfo(publish.getUserId());
        // 封装vo返回
        PublishVo vo = new PublishVo();
        vo.setUserInfo(userInfo);
        vo.setPublish(publish);
        vo.setId(publish.getId().toString());
        System.out.println(vo);
        return ResponseEntity.ok(vo);
    }

    public ResponseEntity pgInfo(String movementId, Integer page, Integer pagesize) {

        //1 根据动态id获取comment
        PageBeanVo pageBeanVo=commentApi.findComment(movementId,page,pagesize);
        List<Comment> items = (List<Comment>) pageBeanVo.getItems();

        List<CommentVo> commentVoList = new ArrayList<>();
        if(CollectionUtil.isNotEmpty(items)){
            for (Comment comment : items) {
                //2 根据发帖人的id获取userInfo
                UserInfo userInfo = userInfoApi.findUserInfo(comment.getUserId());
                //3 封装vo对象（userInfo+comment）
                CommentVo vo = new CommentVo();
                vo.setAvatar(userInfo.getAvatar());
                vo.setNickname(userInfo.getNickname());
                vo.setId(comment.getId().toString());
                vo.setContent(comment.getContent());
                vo.setLikeCount(comment.getLikeCount());
                vo.setCreateDate(RelativeDateFormat.format(new Date(comment.getCreated())));
                commentVoList.add(vo);
            }

        }

        pageBeanVo.setItems(commentVoList);
        return ResponseEntity.ok(pageBeanVo);
    }
}
